/******************** (C) COPYRIGHT 2004 STMicroelectronics ********************
* File Name          : common.c
* Author             : MCD Application Team
* Date First Issued  : 10/25/2004
* Description        : This file provides all the common functions
********************************************************************************
* History:
*  10/25/2004 : Created
*  11/24/2004 : IAP Version 1.0
********************************************************************************
THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH
CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A 
RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR 
CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT OF SUCH 
SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN
IN CONNECTION WITH THEIR PRODUCTS.
********************************************************************************/

#include "common.h"
#include "mem_test.h"
#include "2440lib.h"
#include "uart_fifo.h"

/*******************************************************************************
* Function Name  : Int2Str
* Description    : Convert an Integer to a srting 
* Input 1        : The string
* Input 2        : The intger to be converted  
* Return         : None                                         
*******************************************************************************/
void Int2Str(RAW_U8* str,RAW_U32 intnum)
{
  RAW_U32 i,Div=1000000000,j=0,Status=0;
  for(i=0;i<10;i++)
  {
    str[j++]=(intnum/Div) + 48;
    intnum= intnum%Div;
    Div/=10;
    if ((str[j-1]=='0')&(Status==0))
      j=0;
    else
      Status++;
  }
}
/*******************************************************************************
* Function Name  : Str2Int
* Description    : Convert a srting to an integer 
* Input 1        : The string to be converted
* Input 2        : The intger value  
* Return         : 1 -- Correct
                 : 0 -- Error                                           
*******************************************************************************/
RAW_U32 Str2Int(RAW_U8 *inputstr,RAW_U32 *intnum)
{
	RAW_U32 i,res;
	RAW_U32 val = 0;

	if (inputstr[0] == '0' && (inputstr[1] == 'x'||inputstr[1] == 'X'))
	{	
		if (inputstr[2] == '\0')
		{
			return 0;
		}
		for (i=2;i<11;i++)
		{
			if (inputstr[i] == '\0')
			{
				*intnum = val;
				res = 1;//return 1;
				break;
			}
			if (ISVALIDHEX(inputstr[i]))
			{
				val = (val << 4) + CONVERTHEX(inputstr[i]);
			}	
			else 
			{
				//return 0;//inval input
				res = 0;
				break;
			}	
		}	
		
		if (i>=11) res = 0;	//over 8 digit hex --invalid
	}
	else //max 10-digit decimal input
	{
		for (i=0;i<11;i++)
		{
			if (inputstr[i] == '\0')
			{
				*intnum = val;
				//return 1;
				res =1;
				break;
			}
			else if ((inputstr[i] == 'k' ||inputstr[i] == 'K') && (i>0))
			{
				val = val << 10;
				*intnum = val;
				res = 1;
				break;
			}
			else if ((inputstr[i] == 'm' ||inputstr[i] == 'M') && (i>0))
			{	
				
				val = val << 20;
				*intnum = val;
				res = 1;
				break;
			}
			else if (ISVALIDDEC(inputstr[i]))
				val = val*10 + CONVERTDEC(inputstr[i]);
			else 
			{
				//return 0;//inval input
				res = 0;
				break;
			}	
		}
		if (i>=11) res = 0; //over 10 digit decimal --invalid
	}
	
	return res;
}

/*******************************************************************************
* Function Name  : GetIntegerInput
* Description    : Get an integer from the HyperTerminal 
* Input          : The inetger
* Return         : 1 -- Correct
                 : 0 -- Error                                           
*******************************************************************************/
RAW_U32 GetIntegerInput(RAW_U32 * num)
{
	RAW_U8 inputstr[16];

	while(1)
	{
		GetInputString(inputstr);
		if (inputstr[0] == '\0') continue;
		
		if ((inputstr[0] == 'a'||inputstr[0] == 'A')&& inputstr[1] == '\0')		
		{	
			Uart_SendString("User Cancelled \r\n");
			return 0;
		}	
		
		if (Str2Int(inputstr,num) ==0)	
			Uart_SendString("Error, Input again: \r\n");
		else return 1;	
	}
}

/*******************************************************************************
* Function Name  : GetKey
* Description    : Get a key from the HyperTerminal 
* Input          : None
* Return         : The Key Pressed                                            
*******************************************************************************/
RAW_U8 GetKey(void)
{
	RAW_U8 key;
	//First clear Rx buffer
	//  UART_FifoReset(UARTX,UART_RxFIFO);    
	Uart_TxEmpty(0);
	while (1)
	{
		if(uart_receive_t(&key, 1, RAW_WAIT_FOREVER) == 1)break;
	}
	return key;
}

/*******************************************************************************
* Function Name  : GetInputString	
* Description    : Get Input string from the HyperTerminal 
* Input          : The input string
* Return         : None                                          
*******************************************************************************/
void GetInputString (RAW_U8 * buffP)
{
	RAW_U32 bytes_read = 0;
	RAW_U8 c;
	do
	{
		c = GetKey();
		if (c == '\r')   	
			break;
		if (c == '\b')	//backspace
		{
			if (bytes_read > 0)
			{
				Uart_SendString("\b \b");
				bytes_read --;
			}
			continue;
		}
		if (bytes_read >= CMD_STRING_SIZE )
		{
			Uart_SendString("Command string size overflow\r\n");
			bytes_read = 0;
			continue;
		}
		if (c >= 0x20 && c<= 0x7E)
		{
			buffP[bytes_read++] = c;
			Uart_SendByte(c);
		}	

	}
	while (1);
	Uart_SendString("\n\r");
	buffP[bytes_read] = '\0';
}

extern RAW_U8 file_name[FILE_NAME_LENGTH];
extern void jump_to_dest(void);
/*******************************************************************************
* Function Name  : SerialDownload
* Description    : Download a file via serial port 
* Input          : None 
* Return         : None                                                               
*******************************************************************************/
void SerialDownload (void)
{
	RAW_U8 Number[10];
	RAW_S32 Size, DownloadAddr;
	DownloadAddr = 0x33400000;
	Uart_SendString("Waiting for the file to be sent ... (press 'a' to abort)\n\r");
	Size = Ymodem_Receive((RAW_U8 *)DownloadAddr);
	if (Size > 0)
	{
		Uart_Printf("\n\n\rTransfer Completed!\r\nName: %s\n", file_name);
		Int2Str(Number,Size);
		Uart_Printf("\n\rSize: %d Bytes\r\n", Number);
		jump_to_dest();
	}
	else if (Size < 0)
	{
		Uart_SendString("\n\rAborted by user.\n\r");
	}
	else
	{
		Uart_SendString("\n\rFailed to receive the file!\n\r");
	}
	return;
}
/*******************************************************************************
* Function Name  : Main_Menu	
* Description    : Display the  Main Menu on to HyperTerminal
* Input          : None
* Return         : None                                          
*******************************************************************************/
void Main_Menu(void )
{
	RAW_U8 key;

MainMenu:
	Uart_SendString("\r\n============ Raw-os(mini2440) Bootloader============\r\n");
	Uart_SendString("|1-->Memory Test                                   |\r\n");
	Uart_SendString("|2-->Download And Run(Ymodem)                      |\r\n");
	Uart_SendString("====================================================\r\n");
	do
	{
		key = GetKey();
		if ( key == 0x31)
		{
			MemTest();
			goto MainMenu;
		}
		else if ( key ==0x32)
		{
			SerialDownload();
			goto MainMenu;
		}
		else
		{
			Uart_SendString("Invalid Number ! ==> The number must be either 1 or 2\r\n");
			goto MainMenu;
		}
	}while(1);
}
/*******************(C)COPYRIGHT 2004 STMicroelectronics *****END OF FILE****/

